package com.xiamaliu;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.util.Properties;

/**
 * 自定义连接池 getInstance() 返回 POOL 唯一实例，第一次调用时将执行构造参数
 * 构造函数 Pool() 调用驱动装载 loadDrivers() 函数，连接池创建 createPool() 函数 loadDrivers() 装载驱动
 * createPool() 建连接池，getConnection() 返回一个连接实例，getConnection(lone time) 添加时间限制
 * freeConnection(Connection con) 将 con 连接实例返回到连接池 getNum() 返回空闲连接数
 * getNumActive() 返回当前使用的连接数
 */
public abstract class Pool {

    public String propertiesName = "connection-INF.properties";

    private static Pool instance = null;

    /**
     * 最大连接数
     */
    protected int maxConnect = 100;

    /**
     * 保持连接数
     */
    protected int normalConnect = 10;

    /**
     * 驱动名称
     */
    protected String driverName = null;

    /**
     * 驱动类
     */
    protected Driver driver = null;

    protected Pool() {
        try {
            init();
            loadDrivers(driverName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化所有从配置文件中读取的成员变量
     */
    private void init() throws IOException {
        InputStream is = Pool.class.getResourceAsStream(propertiesName);
        Properties p = new Properties();
        p.load(is);
        this.driverName = p.getProperty("driverName");
        this.maxConnect = Integer.parseInt(p.getProperty("maxConnect"));
        this.normalConnect = Integer.parseInt(p.getProperty("normalConnect"));
    }

    /**
     * 装载和注册所有JDBC驱动程序
     */
    private void loadDrivers(String dri) {
        String driverClassName = dri;
        try {
            driver = (Driver) Class.forName(driverClassName).newInstance();
            DriverManager.registerDriver(driver);
            System.out.println("成功注册JDBC驱动程序：" + driverClassName);
        } catch (Exception e) {
            System.out.println("无法注册JDBC驱动程序：" + driverClassName + ",错误：" + e);
        }
    }

    /**
     * 创建连接池
     */
    public abstract void createPool();

    public static Pool getInstance() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        if (instance == null) {
            instance.init();
            instance = (Pool) Class.forName("").newInstance();
        }
        return instance;
    }

    /**
     * 获得一个可用的链接，如果没有则创建一个连接，且小于最大连接限制
     */
    public abstract Connection getConnection();

    /**
     * 获得一个连接，有时间限制
     */
    public abstract Connection getConnection(long time);

    /**
     * 将连接对象返回给线程池
     */
    public abstract void freeConnection(Connection con);

    /**
     * 返回当前空闲连接数
     */
    public abstract int getnum();

    /**
     * 返回当前正在使用的连接数
     */
    public abstract int getnumActive();

    /**
     * 关闭连接池
     */
    protected synchronized void release() {
        try {
            DriverManager.deregisterDriver(driver);
            System.out.println("撤销JDBC驱动程序：" + driver.getClass().getName());
        } catch (Exception e) {
            System.out.println("无法撤销JDBC驱动程序的注册：" + driver.getClass().getName());
        }
    }
}
